﻿///////////////////////////////////////////////////////////////////////////////
// Activity: program.activity0
// ArmMover service implementation
///////////////////////////////////////////////////////////////////////////////

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Xml;

using ccr = Microsoft.Ccr.Core;
using dss = Microsoft.Dss.Core;
using dssa = Microsoft.Dss.Core.Attributes;
using dssh = Microsoft.Dss.Core.DsspHttp;
using dssm = Microsoft.Dss.ServiceModel.DsspServiceBase;
using dssp = Microsoft.Dss.ServiceModel.Dssp;
using soap = W3C.Soap;

using submgr = Microsoft.Dss.Services.SubscriptionManager;
using timer = Microsoft.Robotics.Services.Sample.Timer.Proxy;
using xinputgamepad = Microsoft.Robotics.Services.Sample.XInputGamepad.Proxy;

namespace Robotics.MoveArm_Sim2.ArmMover
{
    [DisplayName("MoveArm_Sim2ArmMover")]
    [Description("A user defined activity.")]
    [dssa.Contract(Contract.Identifier)]
    public class ArmMoverService : dssm.DsspServiceBase
    {
        // Service state
        [dssa.InitialStatePartner(Optional = true)]
        private ArmMoverState _state;

        // Service operations port
        [dssa.ServicePort("/MoveArm_Sim2/ArmMover", AllowMultipleInstances = false)]
        private ArmMoverOperations _mainPort = new ArmMoverOperations();

        #region Partner services

        [dssa.Partner("SubMgr", Contract = submgr.Contract.Identifier, CreationPolicy = dssa.PartnerCreationPolicy.CreateAlways)]
        private submgr.SubscriptionManagerPort _subMgr = new submgr.SubscriptionManagerPort();

        // Partner: Timer, Contract: http://schemas.microsoft.com/robotics/2006/08/timer.html
        [dssa.Partner("Timer", Contract = timer.Contract.Identifier, CreationPolicy = dssa.PartnerCreationPolicy.UsePartnerListEntry)]
        timer.TimerOperations _timerPort = new timer.TimerOperations();

        // Partner: XInputController, Contract: http://schemas.microsoft.com/robotics/2006/09/xinputgamepad.html
        [dssa.Partner("XInputController", Contract = xinputgamepad.Contract.Identifier, CreationPolicy = dssa.PartnerCreationPolicy.UsePartnerListEntry)]
        xinputgamepad.XInputGamepadOperations _xInputControllerPort = new xinputgamepad.XInputGamepadOperations();

        // Partner: MoveJoint, Contract: 
        [dssa.Partner("MoveJoint", Contract = MoveJoint.Contract.Identifier, CreationPolicy = dssa.PartnerCreationPolicy.UseExistingOrCreate)]
        MoveJoint.MoveJointOperations _moveJointPort = new MoveJoint.MoveJointOperations();

        #endregion

        public ArmMoverService(dssp.DsspServiceCreationPort creationPort)
            : base(creationPort)
        {
        }

        protected override void Start()
        {
            // If there was no initial state partner, then the service state will be null.
            if (_state == null)
            {
                // The state MUST be created before the service starts processing messages.
                _state = new ArmMoverState();
            }

            // The rest of the start process requires the ability to wait for responses from
            // services and from the start handler (if any). So execution now proceeds in an
            // iterator function.
            SpawnIterator(DoStart);
        }

        private IEnumerator<ccr.ITask> DoStart()
        {

            // Start operation handlers and insert into directory service.
            StartHandlers();

            yield break;
        }

        private void StartHandlers()
        {
            // Activate message handlers for this service and insert into the directory.
            base.Start();
        }

        #region Standard DSS message handlers

        [dssa.ServiceHandler(dssa.ServiceHandlerBehavior.Concurrent)]
        public virtual IEnumerator<ccr.ITask> GetHandler(Get get)
        {
            get.ResponsePort.Post(_state);
            yield break;
        }

        [dssa.ServiceHandler(dssa.ServiceHandlerBehavior.Concurrent)]
        public virtual IEnumerator<ccr.ITask> HttpGetHandler(dssh.HttpGet httpGet)
        {
            httpGet.ResponsePort.Post(new dssh.HttpResponseType(_state));
            yield break;
        }

        [dssa.ServiceHandler(dssa.ServiceHandlerBehavior.Exclusive)]
        public virtual IEnumerator<ccr.ITask> ReplaceHandler(Replace replace)
        {
            _state = replace.Body;

            replace.ResponsePort.Post(dssp.DefaultReplaceResponseType.Instance);
            base.SendNotification<Replace>(_subMgr, replace);

            yield break;
        }

        [dssa.ServiceHandler(dssa.ServiceHandlerBehavior.Concurrent)]
        public virtual IEnumerator<ccr.ITask> SubscribeHandler(Subscribe subscribe)
        {
            dssp.SubscribeRequestType request = subscribe.Body;

            yield return ccr.Arbiter.Choice(
                SubscribeHelper(_subMgr, request, subscribe.ResponsePort),
                delegate(ccr.SuccessResult success)
                {
                    base.SendNotification<Replace>(_subMgr, request.Subscriber, _state);
                },
                delegate(Exception e) { }
            );
        }

        #endregion

        #region Custom message handlers

        [dssa.ServiceHandler(dssa.ServiceHandlerBehavior.Exclusive)]
        public virtual IEnumerator<ccr.ITask> SetPollIntervalHandler(SetPollInterval message)
        {
            SetPollIntervalMessageHandler handler = new SetPollIntervalMessageHandler(this, Environment.TaskQueue);

            SpawnIterator(message.Body, message.ResponsePort, handler.RunHandler);

            yield return ccr.Arbiter.Receive(false, handler.Complete, EmptyHandler);

            if (handler.StateChanged == true)
            {
                base.SendNotification<Replace>(_subMgr, _state);
            }
        }

        #endregion

        #region SetPollIntervalMessageHandler class

        class SetPollIntervalMessageHandler : HandlerBase
        {
            ///////////////////////////////////////////////////////////////////
            // request
            // [(__use__00.snippet.snippet.noop - __use__00.snippet.snippet.expr - __use__00.snippet.snippet.join)] - __use__00.snippet.call - __use__00.snippet.call.iftype
            // expr6 - element2
            // element3
            // __use__1.snippet0.snippet.noop - [(__use__1.snippet0.snippet.expr0 - __use__1.snippet0.snippet.join)(__use__1.snippet0.snippet.expr - &__use__1.snippet0.snippet.join)] - __use__1.snippet0.call - __use__1.snippet0.call.iftype
            // expr7 - &element3
            // element0
            // __use__10.snippet0.snippet.noop - [(__use__10.snippet0.snippet.expr0 - __use__10.snippet0.snippet.join)(__use__10.snippet0.snippet.expr - &__use__10.snippet0.snippet.join)] - __use__10.snippet0.call - __use__10.snippet0.call.iftype
            // expr70 - &element0
            // element1
            // __use__100.snippet.snippet.noop - [(__use__100.snippet.snippet.expr0 - __use__100.snippet.snippet.join)(__use__100.snippet.snippet.expr - &__use__100.snippet.snippet.join)] - __use__100.snippet.call - __use__100.snippet.call.iftype
            // expr700 - &element1
            // element10
            // __use__101.snippet.snippet.noop - [(__use__101.snippet.snippet.expr0 - __use__101.snippet.snippet.join)(__use__101.snippet.snippet.expr - &__use__101.snippet.snippet.join)] - __use__101.snippet.call - __use__101.snippet.call.iftype
            // expr701 - &element10
            // element11
            // __use__102.snippet.snippet.noop - [(__use__102.snippet.snippet.expr0 - __use__102.snippet.snippet.join)(__use__102.snippet.snippet.expr - &__use__102.snippet.snippet.join)] - __use__102.snippet.call - __use__102.snippet.call.iftype
            // expr702 - &element11
            // element12
            // __use__103.snippet.snippet.noop - [(__use__103.snippet.snippet.expr0 - __use__103.snippet.snippet.join)(__use__103.snippet.snippet.expr - &__use__103.snippet.snippet.join)] - __use__103.snippet.call - __use__103.snippet.call.iftype
            // expr703 - &element12
            // expr - set - expr0
            // element
            // __use__0.snippet0.snippet.noop - __use__0.snippet0.snippet.expr - __use__0.snippet0.snippet.join
            // __use__0.snippet0.call - __use__0.snippet0.call.iftype
            // __use__.snippet0.call - __use__.snippet0.call.iftype
            // if if{expr3 - set3}elseif{expr30 - set30}elseif{expr31 - set31}elseif{expr300 - set300}else{}
            // if0 if{expr32 - set32}elseif{expr301 - set301}elseif{expr310 - set310}elseif{expr3000 - set3000}else{}
            // if1 if{expr33 - set33}elseif{expr302 - set302}elseif{expr311 - set311}elseif{expr3001 - set3001}else{}
            // if2 if{expr330 - set330}elseif{expr3020 - set3020}else{}
            // if3 if{expr4 - set0}elseif{expr5 - set1}else{}
            // if10 if{expr2 - set2}elseif{expr21 - set20}elseif{expr210 - set21}elseif{expr211 - set22}else{}
            // expr1 - &element
            // snippet.element
            ///////////////////////////////////////////////////////////////////

            public SetPollIntervalMessageHandler(ArmMoverService service, ccr.DispatcherQueue queue)
                : base(service, queue)
            {

                // Activate merge handlers
                Activate(ccr.Arbiter.Receive(true, _mergeAlpha, _mergeAlphaHandler));
                Activate(ccr.Arbiter.Receive(true, _mergeBeta, _mergeBetaHandler));
                Activate(ccr.Arbiter.Receive(true, _mergeGamma, _mergeGammaHandler));
                Activate(ccr.Arbiter.Receive(true, _mergeDelta, _mergeDeltaHandler));
                Activate(ccr.Arbiter.Receive(true, _mergeEpsilon, _mergeEpsilonHandler));
                Activate(ccr.Arbiter.Receive(true, _mergeZeta, _mergeZetaHandler));
                Activate(ccr.Arbiter.Receive(true, _mergeEta, _mergeEtaHandler));
                Activate(ccr.Arbiter.Receive(true, _mergeTheta, _mergeThetaHandler));

                // Register joins with base class to manage active count for incomplete joins.
                base.RegisterJoin(_joinAlphaPorts);
                // Activate Join handlers
                Activate(ccr.Arbiter.MultiplePortReceive(true, _joinAlphaPorts, _joinAlphaHandler));
            }

            dssp.DsspResponsePort<SetPollIntervalResponse> _responsePort;

            ///////////////////////////////////////////////////////////////////
            // request
            // expr - set - expr0
            // [(__use__00.snippet.snippet.noop - __use__00.snippet.snippet.expr - __use__00.snippet.snippet.join)] - __use__00.snippet.call - __use__00.snippet.call.iftype
            // snippet.element
            // element
            ///////////////////////////////////////////////////////////////////

            public IEnumerator<ccr.ITask> RunHandler(SetPollIntervalRequest message, dssp.DsspResponsePort<SetPollIntervalResponse> responsePort)
            {
                _responsePort = responsePort;
                Increment();


                base.StateChanged = true;

                ArmMoverState a = new ArmMoverState();
                State.PollInterval = message.PollInterval;
                a.PollInterval = State.PollInterval;

                _responsePort.Post(new SetPollIntervalResponse());


                Increment();
                _mergeTheta.Post(State.PollInterval);

                timer.SetTimerRequest request = new timer.SetTimerRequest();
                request.Interval = 5000;

                Increment();
                Activate(
                    ccr.Arbiter.Choice(
                        TimerPort.Wait(request),
                        OnWaitSuccess,
                        delegate(soap.Fault fault)
                        {
                            base.FaultHandler(fault, @"TimerPort.Wait(request)");
                            Decrement();
                        }
                    )
                );

                Decrement();

                yield return WaitUntilComplete();
            }

            ccr.Port<int> _mergeTheta = new ccr.Port<int>();

            ///////////////////////////////////////////////////////////////////
            // __use__0.snippet0.snippet.noop - __use__0.snippet0.snippet.expr - __use__0.snippet0.snippet.join
            ///////////////////////////////////////////////////////////////////

            void _mergeThetaHandler(int message)
            {
                Increment();
                _joinAlphaPorts[0].Post(message);

                Decrement();
            }

            ///////////////////////////////////////////////////////////////////
            // __use__0.snippet0.call - __use__0.snippet0.call.iftype
            ///////////////////////////////////////////////////////////////////

            void _joinAlphaHandler(object[] args)
            {
                JoinAlpha message = new JoinAlpha(args);

                Increment();
                Activate(
                    ccr.Arbiter.Choice(
                        TimerPort.Wait((timer.SetTimerRequest)message),
                        OnWait1Success,
                        delegate(soap.Fault fault)
                        {
                            base.FaultHandler(fault, @"TimerPort.Wait((timer.SetTimerRequest)message)");
                            Decrement();
                        }
                    )
                );

                Decrement(args.Length);
            }

            void OnWaitSuccess(dssp.DefaultSubmitResponseType response)
            {

                Increment();
                _mergeAlpha.Post(State.PollInterval);

                Decrement();
            }

            void OnWait1Success(dssp.DefaultSubmitResponseType response)
            {

                Increment();
                _mergeTheta.Post(State.PollInterval);


                Increment();
                Activate(
                    ccr.Arbiter.Choice(
                        XInputControllerPort.Get(new dssp.GetRequestType()),
                        OnGetRequestTypeSuccess,
                        delegate(soap.Fault fault)
                        {
                            base.FaultHandler(fault, @"XInputControllerPort.Get(new dssp.GetRequestType())");
                            Decrement();
                        }
                    )
                );

                Decrement();
            }

            void OnGetRequestTypeSuccess(xinputgamepad.XInputGamepadState response)
            {

                if (response.Thumbsticks.RightX > 0.8D)
                {
                    base.StateChanged = true;
                    State.WristRotate4 = FloatCast(State.WristRotate4 - 0.05D);
                }
                else if (response.Thumbsticks.RightX < -0.8D)
                {
                    base.StateChanged = true;
                    State.WristRotate4 = FloatCast(State.WristRotate4 + 0.05D);
                }
                else if (response.Thumbsticks.RightX > 0.1D)
                {
                    base.StateChanged = true;
                    State.WristRotate4 = FloatCast(State.WristRotate4 - 0.02D);
                }
                else if (response.Thumbsticks.RightX < -0.1D)
                {
                    base.StateChanged = true;
                    State.WristRotate4 = FloatCast(State.WristRotate4 + 0.02D);
                }


                if (response.Buttons.X)
                {
                    base.StateChanged = true;
                    State.Gripper5 = FloatCast(State.Gripper5 - 0.2D);
                }
                else if (response.Buttons.B)
                {
                    base.StateChanged = true;
                    State.Gripper5 = FloatCast(State.Gripper5 + 0.2D);
                }


                if (response.Buttons.Y)
                {
                    base.StateChanged = true;
                    State.Wrist3 = FloatCast(State.Wrist3 + 0.05D);
                }
                else if (response.Buttons.A)
                {
                    base.StateChanged = true;
                    State.Wrist3 = FloatCast(State.Wrist3 - 0.05D);
                }


                if (response.Thumbsticks.RightY > 0.8D)
                {
                    base.StateChanged = true;
                    State.Elbow2 = FloatCast(State.Elbow2 + 0.05D);
                }
                else if (response.Thumbsticks.RightY < -0.8D)
                {
                    base.StateChanged = true;
                    State.Elbow2 = FloatCast(State.Elbow2 - 0.05D);
                }
                else if (response.Thumbsticks.RightY > 0.1D)
                {
                    base.StateChanged = true;
                    State.Elbow2 = FloatCast(State.Elbow2 + 0.02D);
                }
                else if (response.Thumbsticks.RightY < -0.1D)
                {
                    base.StateChanged = true;
                    State.Elbow2 = FloatCast(State.Elbow2 - 0.02D);
                }


                if (response.Thumbsticks.LeftY > 0.8D)
                {
                    base.StateChanged = true;
                    State.Shoulder1 = FloatCast(State.Shoulder1 - 0.05D);
                }
                else if (response.Thumbsticks.LeftY < -0.8D)
                {
                    base.StateChanged = true;
                    State.Shoulder1 = FloatCast(State.Shoulder1 + 0.05D);
                }
                else if (response.Thumbsticks.LeftY > 0.1D)
                {
                    base.StateChanged = true;
                    State.Shoulder1 = FloatCast(State.Shoulder1 - 0.02D);
                }
                else if (response.Thumbsticks.LeftY < -0.1D)
                {
                    base.StateChanged = true;
                    State.Shoulder1 = FloatCast(State.Shoulder1 + 0.02D);
                }


                if (response.Thumbsticks.LeftX > 0.8D)
                {
                    base.StateChanged = true;
                    State.Base0 = FloatCast(State.Base0 + 0.05D);
                }
                else if (response.Thumbsticks.LeftX < -0.8D)
                {
                    base.StateChanged = true;
                    State.Base0 = FloatCast(State.Base0 - 0.05D);
                }
                else if (response.Thumbsticks.LeftX > 0.1D)
                {
                    base.StateChanged = true;
                    State.Base0 = FloatCast(State.Base0 + 0.02D);
                }
                else if (response.Thumbsticks.LeftX < -0.1D)
                {
                    base.StateChanged = true;
                    State.Base0 = FloatCast(State.Base0 - 0.02D);
                }

                Decrement();
            }

            ccr.Port<int> _mergeAlpha = new ccr.Port<int>();

            ///////////////////////////////////////////////////////////////////
            // element12
            // element11
            // element10
            // element1
            // element0
            // element3
            ///////////////////////////////////////////////////////////////////

            void _mergeAlphaHandler(int message)
            {

                Increment();
                _mergeBeta.Post(message);


                Increment();
                _mergeGamma.Post(message);


                Increment();
                _mergeDelta.Post(message);


                Increment();
                _mergeEpsilon.Post(message);


                Increment();
                _mergeZeta.Post(message);


                Increment();
                _mergeEta.Post(message);

                Decrement();
            }

            ccr.Port<int> _mergeBeta = new ccr.Port<int>();

            ///////////////////////////////////////////////////////////////////
            // __use__103.snippet.snippet.noop - [(__use__103.snippet.snippet.expr0 - __use__103.snippet.snippet.join)(__use__103.snippet.snippet.expr - &__use__103.snippet.snippet.join)] - __use__103.snippet.call - __use__103.snippet.call.iftype
            ///////////////////////////////////////////////////////////////////

            void _mergeBetaHandler(int message)
            {
                MoveJoint.JointParamsRequest request = new MoveJoint.JointParamsRequest();
                request.Angle = State.Gripper5;
                request.JointName = @"Gripper-Joint5";

                Increment();
                Activate(
                    ccr.Arbiter.Choice(
                        MoveJointPort.JointParams(request),
                        OnJointParamsSuccess,
                        delegate(soap.Fault fault)
                        {
                            base.FaultHandler(fault, @"MoveJointPort.JointParams(request)");
                            Decrement();
                        }
                    )
                );

                Decrement();
            }

            ccr.Port<int> _mergeGamma = new ccr.Port<int>();

            ///////////////////////////////////////////////////////////////////
            // __use__102.snippet.snippet.noop - [(__use__102.snippet.snippet.expr0 - __use__102.snippet.snippet.join)(__use__102.snippet.snippet.expr - &__use__102.snippet.snippet.join)] - __use__102.snippet.call - __use__102.snippet.call.iftype
            ///////////////////////////////////////////////////////////////////

            void _mergeGammaHandler(int message)
            {
                MoveJoint.JointParamsRequest request = new MoveJoint.JointParamsRequest();
                request.Angle = State.WristRotate4;
                request.JointName = @"WristRotate-Joint4";

                Increment();
                Activate(
                    ccr.Arbiter.Choice(
                        MoveJointPort.JointParams(request),
                        OnJointParams1Success,
                        delegate(soap.Fault fault)
                        {
                            base.FaultHandler(fault, @"MoveJointPort.JointParams(request)");
                            Decrement();
                        }
                    )
                );

                Decrement();
            }

            ccr.Port<int> _mergeDelta = new ccr.Port<int>();

            ///////////////////////////////////////////////////////////////////
            // __use__101.snippet.snippet.noop - [(__use__101.snippet.snippet.expr0 - __use__101.snippet.snippet.join)(__use__101.snippet.snippet.expr - &__use__101.snippet.snippet.join)] - __use__101.snippet.call - __use__101.snippet.call.iftype
            ///////////////////////////////////////////////////////////////////

            void _mergeDeltaHandler(int message)
            {
                MoveJoint.JointParamsRequest request = new MoveJoint.JointParamsRequest();
                request.Angle = State.Wrist3;
                request.JointName = @"Wrist-Joint3";

                Increment();
                Activate(
                    ccr.Arbiter.Choice(
                        MoveJointPort.JointParams(request),
                        OnJointParams2Success,
                        delegate(soap.Fault fault)
                        {
                            base.FaultHandler(fault, @"MoveJointPort.JointParams(request)");
                            Decrement();
                        }
                    )
                );

                Decrement();
            }

            ccr.Port<int> _mergeEpsilon = new ccr.Port<int>();

            ///////////////////////////////////////////////////////////////////
            // __use__100.snippet.snippet.noop - [(__use__100.snippet.snippet.expr0 - __use__100.snippet.snippet.join)(__use__100.snippet.snippet.expr - &__use__100.snippet.snippet.join)] - __use__100.snippet.call - __use__100.snippet.call.iftype
            ///////////////////////////////////////////////////////////////////

            void _mergeEpsilonHandler(int message)
            {
                MoveJoint.JointParamsRequest request = new MoveJoint.JointParamsRequest();
                request.Angle = State.Elbow2;
                request.JointName = @"Elbow-Joint2";

                Increment();
                Activate(
                    ccr.Arbiter.Choice(
                        MoveJointPort.JointParams(request),
                        OnJointParams3Success,
                        delegate(soap.Fault fault)
                        {
                            base.FaultHandler(fault, @"MoveJointPort.JointParams(request)");
                            Decrement();
                        }
                    )
                );

                Decrement();
            }

            ccr.Port<int> _mergeZeta = new ccr.Port<int>();

            ///////////////////////////////////////////////////////////////////
            // __use__10.snippet0.snippet.noop - [(__use__10.snippet0.snippet.expr0 - __use__10.snippet0.snippet.join)(__use__10.snippet0.snippet.expr - &__use__10.snippet0.snippet.join)] - __use__10.snippet0.call - __use__10.snippet0.call.iftype
            ///////////////////////////////////////////////////////////////////

            void _mergeZetaHandler(int message)
            {
                MoveJoint.JointParamsRequest request = new MoveJoint.JointParamsRequest();
                request.Angle = State.Shoulder1;
                request.JointName = @"Shoulder-Joint1";

                Increment();
                Activate(
                    ccr.Arbiter.Choice(
                        MoveJointPort.JointParams(request),
                        OnJointParams4Success,
                        delegate(soap.Fault fault)
                        {
                            base.FaultHandler(fault, @"MoveJointPort.JointParams(request)");
                            Decrement();
                        }
                    )
                );

                Decrement();
            }

            ccr.Port<int> _mergeEta = new ccr.Port<int>();

            ///////////////////////////////////////////////////////////////////
            // __use__1.snippet0.snippet.noop - [(__use__1.snippet0.snippet.expr0 - __use__1.snippet0.snippet.join)(__use__1.snippet0.snippet.expr - &__use__1.snippet0.snippet.join)] - __use__1.snippet0.call - __use__1.snippet0.call.iftype
            ///////////////////////////////////////////////////////////////////

            void _mergeEtaHandler(int message)
            {
                MoveJoint.JointParamsRequest request = new MoveJoint.JointParamsRequest();
                request.Angle = State.Base0;
                request.JointName = @"Base-Joint0";

                Increment();
                Activate(
                    ccr.Arbiter.Choice(
                        MoveJointPort.JointParams(request),
                        OnJointParams5Success,
                        delegate(soap.Fault fault)
                        {
                            base.FaultHandler(fault, @"MoveJointPort.JointParams(request)");
                            Decrement();
                        }
                    )
                );

                Decrement();
            }

            void OnJointParamsSuccess(MoveJoint.JointParamsResponse response)
            {

                Increment();
                _mergeBeta.Post(500);

                Decrement();
            }

            void OnJointParams1Success(MoveJoint.JointParamsResponse response)
            {

                Increment();
                _mergeGamma.Post(500);

                Decrement();
            }

            void OnJointParams2Success(MoveJoint.JointParamsResponse response)
            {

                Increment();
                _mergeDelta.Post(500);

                Decrement();
            }

            void OnJointParams3Success(MoveJoint.JointParamsResponse response)
            {

                Increment();
                _mergeEpsilon.Post(500);

                Decrement();
            }

            void OnJointParams4Success(MoveJoint.JointParamsResponse response)
            {

                Increment();
                _mergeZeta.Post(500);

                Decrement();
            }

            void OnJointParams5Success(MoveJoint.JointParamsResponse response)
            {

                Increment();
                _mergeEta.Post(500);

                Decrement();
            }

            class JoinAlpha
            {
                public int Interval;

                public JoinAlpha()
                {
                }

                public JoinAlpha(object[] args)
                {
                    Interval = (int)args[0];
                }

                public static explicit operator timer.SetTimerRequest(JoinAlpha join)
                {
                    timer.SetTimerRequest request = new timer.SetTimerRequest();

                    request.Interval = join.Interval;
                    return request;
                }
            }

            ccr.Port<object>[] _secondJoinAlphaPorts = new ccr.Port<object>[1]{
                new ccr.Port<object>()
            };

            class JoinBeta
            {
                public string JointName;
                public string Angle;

                public JoinBeta()
                {
                }

                public JoinBeta(object[] args)
                {
                    JointName = args[0].ToString();
                    Angle = args[1].ToString();
                }
            }

            ccr.Port<object>[] _joinBetaPorts = new ccr.Port<object>[2]{
                new ccr.Port<object>(),
                new ccr.Port<object>()
            };

            ccr.Port<object>[] _secondJoinBetaPorts = new ccr.Port<object>[2]{
                new ccr.Port<object>(),
                new ccr.Port<object>()
            };

            ccr.Port<object>[] _thirdJoinBetaPorts = new ccr.Port<object>[2]{
                new ccr.Port<object>(),
                new ccr.Port<object>()
            };

            ccr.Port<object>[] _fourthJoinBetaPorts = new ccr.Port<object>[2]{
                new ccr.Port<object>(),
                new ccr.Port<object>()
            };

            ccr.Port<object>[] _fifthJoinBetaPorts = new ccr.Port<object>[2]{
                new ccr.Port<object>(),
                new ccr.Port<object>()
            };

            ccr.Port<object>[] _sixthJoinBetaPorts = new ccr.Port<object>[2]{
                new ccr.Port<object>(),
                new ccr.Port<object>()
            };

            ccr.Port<object>[] _joinAlphaPorts = new ccr.Port<object>[1]{
                new ccr.Port<object>()
            };
        }

        #endregion

        #region Handler utility base class

        class HandlerBase : ccr.CcrServiceBase
        {
            ccr.Port<ccr.EmptyValue> _complete = new ccr.Port<ccr.EmptyValue>();
            ccr.Port<ccr.EmptyValue> _shutdown = new ccr.Port<ccr.EmptyValue>();
            List<ccr.Port<object>[]> _joins = new List<ccr.Port<object>[]>();
            ArmMoverService _service;
            int _count;

            public HandlerBase(ArmMoverService service, ccr.DispatcherQueue queue)
                : base(queue)
            {
                _service = service;
            }

            protected ArmMoverState State
            {
                get { return _service._state; }
            }

            bool _stateChanged;

            public bool StateChanged
            {
                get { return _stateChanged; }
                set { _stateChanged = value; }
            }

            protected timer.TimerOperations TimerPort
            {
                get { return _service._timerPort; }
            }

            protected xinputgamepad.XInputGamepadOperations XInputControllerPort
            {
                get { return _service._xInputControllerPort; }
            }

            protected MoveJoint.MoveJointOperations MoveJointPort
            {
                get { return _service._moveJointPort; }
            }

            public ccr.Port<ccr.EmptyValue> Complete
            {
                get { return _complete; }
            }

            protected void Increment()
            {
                System.Threading.Interlocked.Increment(ref _count);
            }

            protected void Decrement()
            {
                int offset = 0;

                foreach (ccr.Port<object>[] join in _joins)
                {
                    bool complete = true;
                    int joinCount = 0;

                    foreach (ccr.Port<object> sink in join)
                    {
                        if (sink.ItemCount != 0)
                        {
                            joinCount += sink.ItemCount;
                        }
                        else
                        {
                            complete = false;
                        }
                    }
                    if (complete == false)
                    {
                        offset += joinCount;
                    }
                }

                if (System.Threading.Interlocked.Decrement(ref _count) <= offset)
                {
                    _shutdown.Post(ccr.EmptyValue.SharedInstance);
                    _complete.Post(ccr.EmptyValue.SharedInstance);
                }
            }

            protected void Decrement(int count)
            {
                for(int i = 0; i < count; i++)
                {
                    Decrement();
                }
            }

            protected void RegisterJoin(ccr.Port<object>[] join)
            {
                _joins.Add(join);
            }

            protected ccr.ITask WaitUntilComplete()
            {
                return ccr.Arbiter.Receive(false, _shutdown, NullDelegate);
            }

            protected static void NullDelegate(ccr.EmptyValue token)
            {
            }

            protected void SendNotification<T>(object notification)
                where T : dssp.DsspOperation, new()
            {
                _service.SendNotification<T>(_service._subMgr, notification);
            }

            protected void FaultHandler(soap.Fault fault, string msg)
            {
                _service.LogError(null, msg, fault);
            }

            protected static string Stringize(object obj)
            {
                if (obj == null)
                {
                    return string.Empty;
                }
                else
                {
                    return obj.ToString();
                }
            }

            protected void UnhandledResponse(W3C.Soap.Fault fault)
            {
                _service.LogError("Unhandled fault response from partner service", fault);
                Decrement();
            }

            protected void UnhandledResponse<T>(T response)
            {
                Decrement();
            }

            #region Type Cast Functions

            protected static bool BoolCast(object obj)
            {
                if (obj != null && obj is IConvertible)
                {
                    try
                    {
                        return ((IConvertible)obj).ToBoolean(System.Globalization.CultureInfo.InvariantCulture);
                    }
                    catch (FormatException)
                    {
                    }
                }
                return false;
            }

            protected static byte ByteCast(object obj)
            {
                if (obj != null && obj is IConvertible)
                {
                    try
                    {
                        return ((IConvertible)obj).ToByte(System.Globalization.CultureInfo.InvariantCulture);
                    }
                    catch (FormatException)
                    {
                    }
                }
                return 0;
            }

            protected static char CharCast(object obj)
            {
                if (obj != null && obj is IConvertible)
                {
                    try
                    {
                        return ((IConvertible)obj).ToChar(System.Globalization.CultureInfo.InvariantCulture);
                    }
                    catch (FormatException)
                    {
                    }
                }
                return '\0';
            }

            protected static decimal DecimalCast(object obj)
            {
                if (obj != null && obj is IConvertible)
                {
                    try
                    {
                        return ((IConvertible)obj).ToDecimal(System.Globalization.CultureInfo.InvariantCulture);
                    }
                    catch (FormatException)
                    {
                    }
                }
                return 0;
            }

            protected static double DoubleCast(object obj)
            {
                if (obj != null && obj is IConvertible)
                {
                    try
                    {
                        return ((IConvertible)obj).ToDouble(System.Globalization.CultureInfo.InvariantCulture);
                    }
                    catch (FormatException)
                    {
                    }
                }
                return 0;
            }

            protected static float FloatCast(object obj)
            {
                if (obj != null && obj is IConvertible)
                {
                    try
                    {
                        return ((IConvertible)obj).ToSingle(System.Globalization.CultureInfo.InvariantCulture);
                    }
                    catch (FormatException)
                    {
                    }
                }
                return 0;
            }

            protected static int IntCast(object obj)
            {
                if (obj != null && obj is IConvertible)
                {
                    try
                    {
                        return ((IConvertible)obj).ToInt32(System.Globalization.CultureInfo.InvariantCulture);
                    }
                    catch (FormatException)
                    {
                    }
                }
                return 0;
            }

            protected static long LongCast(object obj)
            {
                if (obj != null && obj is IConvertible)
                {
                    try
                    {
                        return ((IConvertible)obj).ToInt64(System.Globalization.CultureInfo.InvariantCulture);
                    }
                    catch (FormatException)
                    {
                    }
                }
                return 0;
            }

            protected static sbyte SByteCast(object obj)
            {
                if (obj != null && obj is IConvertible)
                {
                    try
                    {
                        return ((IConvertible)obj).ToSByte(System.Globalization.CultureInfo.InvariantCulture);
                    }
                    catch (FormatException)
                    {
                    }
                }
                return 0;
            }

            protected static short ShortCast(object obj)
            {
                if (obj != null && obj is IConvertible)
                {
                    try
                    {
                        return ((IConvertible)obj).ToInt16(System.Globalization.CultureInfo.InvariantCulture);
                    }
                    catch (FormatException)
                    {
                    }
                }
                return 0;
            }

            protected static uint UIntCast(object obj)
            {
                if (obj != null && obj is IConvertible)
                {
                    try
                    {
                        return ((IConvertible)obj).ToUInt32(System.Globalization.CultureInfo.InvariantCulture);
                    }
                    catch (FormatException)
                    {
                    }
                }
                return 0;
            }

            protected static ulong ULongCast(object obj)
            {
                if (obj != null && obj is IConvertible)
                {
                    try
                    {
                        return ((IConvertible)obj).ToUInt64(System.Globalization.CultureInfo.InvariantCulture);
                    }
                    catch (FormatException)
                    {
                    }
                }
                return 0;
            }

            protected static ushort UShortCast(object obj)
            {
                if (obj != null && obj is IConvertible)
                {
                    try
                    {
                        return ((IConvertible)obj).ToUInt16(System.Globalization.CultureInfo.InvariantCulture);
                    }
                    catch (FormatException)
                    {
                    }
                }
                return 0;
            }

            #endregion

            #region List Functions

            protected List<T> ListAdd<T>(List<T> list, T item)
            {
                List<T> output = new List<T>(list);
                output.Add(item);
                return output;
            }

            protected List<T> ListConcat<T>(List<T> head, List<T> tail)
            {
                List<T> output = new List<T>(head);
                output.AddRange(tail);
                return output;
            }

            protected int ListIndex<T>(List<T> list, T item)
            {
                return list.IndexOf(item);
            }

            protected List<T> ListRemove<T>(List<T> list, int index)
            {
                List<T> output = new List<T>(list);
                output.RemoveAt(index);
                return output;
            }

            protected List<T> ListReverse<T>(List<T> list)
            {
                List<T> output = new List<T>(list);
                output.Reverse();
                return output;
            }

            protected List<T> ListSort<T>(List<T> list)
            {
                List<T> output = new List<T>(list);
                output.Sort();
                return output;
            }

            protected List<T> ListInsert<T>(List<T> list, T item, int index)
            {
                List<T> output = new List<T>(list);
                output.Insert(index, item);
                return output;
            }

            #endregion
        }

        #endregion
    }
}
